package com.poetry.vup.common.util;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.poetry.vup.common.exception.KabobExceptionUtil;
import com.poetry.vup.common.result.ResultCode;


import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 对象序列化和反序列化的jackson实现工具类
 * @author mwan
 *
 */
public class JacksonUtil {
	
	public static<T> T objectToObject(Object obj, Class<T> A) {
		try {
			if(obj == null) return null;
			ObjectMapper mapper = new ObjectMapper();
			JavaTimeModule timeModule = new JavaTimeModule();
			//禁用遇到未知属性抛出异常
			mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
			//空字符视传为null
			mapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL);
	        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
	        timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
	        mapper.registerModule(timeModule);
			String json = mapper.writeValueAsString(obj);
			T targetObj = mapper.readValue(json, A);
			return targetObj;
		}catch (IOException e) {
			KabobExceptionUtil.throwError(ResultCode.FAILED, "服务器发生对象转换异常", e);
			return null;
		}
	}
	
	public static String objectToString(Object obj) {
		try {
			ObjectMapper mapper = new ObjectMapper();
			String json = mapper.writeValueAsString(obj);
			return json;
		}catch (IOException e) {
			KabobExceptionUtil.throwError(ResultCode.FAILED, "服务器发生对象转换异常", e);
			return null;
		}
	}
	
	public static<T> T stringToObject(String str, Class<T> A) {
		try {
			ObjectMapper mapper = new ObjectMapper();
			T obj = mapper.readValue(str, A);
			return obj;
		} catch (IOException e) {
			KabobExceptionUtil.throwError(ResultCode.FAILED, "服务器发生对象转换异常", e);
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	public static <T> Object stringToListObject(String str, Class<T> A) {
		
		try {
			ObjectMapper mapper = new ObjectMapper();
			if(A == String.class) {
				List<String> obj = mapper.readValue(str, ArrayList.class);
				return obj;
			}else {
				JavaType jt = mapper.getTypeFactory().constructParametricType(ArrayList.class, A);
				List<T> obj = mapper.readValue(str, jt);
				return obj;
			}
		} catch (IOException e) {
			KabobExceptionUtil.throwError(ResultCode.FAILED, "服务器发生对象转换异常", e);
			return null;
		}
	}
	
	public static <T> List<T> listToListObject(List<?> objList, Class<T> A) {
		List<T> results = new ArrayList<T>(objList.size());
		for(Object obj : objList) {
			results.add((T)objectToObject(obj, A));
		}
		return results;
	}

}
